/**
 * 
 */
package fr.ants.controller.listener;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;

import fr.ants.controller.clock.Clock;
import fr.ants.controller.command.AccelerateCommand;
import fr.ants.controller.command.DeleteCommand;
import fr.ants.controller.command.ExitCommand;
import fr.ants.controller.command.LoadImageCommand;
import fr.ants.controller.command.NewObstacleCommand;
import fr.ants.controller.command.NewResourceCommand;
import fr.ants.controller.command.PlayPauseCommand;
import fr.ants.controller.command.SetRendererCommand;
import fr.ants.controller.command.SlowCommand;
import fr.ants.controller.command.StatsCommand;
import fr.ants.controller.command.StopCommand;
import fr.ants.view.Items;
import fr.ants.view.MainFrame;
import fr.ants.view.Renderer;
import fr.ants.view.Selection;
import fr.ants.view.component.PngFileFilter;
import fr.ants.view.panel.Canvas;

/**
 * Listener for the control buttons.
 * 
 * @author Guillaume Ruscassie
 * 
 */
public class ButtonsListener implements MouseListener, ActionListener,
		MouseMotionListener {
	private MainFrame frame;
	/**
	 * command accelerate.
	 */
	private AccelerateCommand accelerate;
	/**
	 * command slow.
	 */
	private SlowCommand slow;
	/**
	 * command play pause.
	 */
	private PlayPauseCommand playPause;
	/**
	 * command stop.
	 */
	private StopCommand stop;

	/**
	 * command exit.
	 */
	private ExitCommand exit;
	/**
	 * command to create a new resource.
	 */
	private NewResourceCommand newResourceCommand;
	/**
	 * command to create a new obstacle.
	 */
	private NewObstacleCommand newObstacleCommand;
	/**
	 * Canvas.
	 */
	private Canvas canvas;
	/**
	 * command to delete a nest or a resource.
	 */
	private DeleteCommand deleteCommand;
	/**
	 * Clock.
	 */
	private Clock clock;
	/**
	 * command to export the stats.
	 */
	private StatsCommand statsCommand;
	/**
	 * command to set the renderer.
	 */
	private SetRendererCommand setRendererCommand;

	/**
	 * Build.
	 * 
	 * @param clock
	 *            clock
	 * @param mainFrame
	 *            frame
	 */
	public ButtonsListener(Clock clock, MainFrame frame) {
		this.frame = frame;
		this.clock = clock;
		accelerate = new AccelerateCommand(this.clock);
		slow = new SlowCommand(this.clock);
		stop = new StopCommand(this.clock);
		playPause = new PlayPauseCommand(this.clock);
		exit = new ExitCommand(stop, frame);
		deleteCommand = new DeleteCommand(this.clock);
		statsCommand = new StatsCommand(clock);
		setRendererCommand = new SetRendererCommand();
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if (e.getComponent() instanceof JButton) {
			JButton button = (JButton) e.getComponent();
			if (button.isEnabled()) {
				// search the icon where the user have click
				Items icones = Items.getFromActionCommand(button
						.getActionCommand());
				clickOnMouse(icones);
			}
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Items icones = Items.getFromActionCommand(e.getActionCommand());
		if (icones != null) {
			clickOnMouse(icones);
		} else if (e.getSource().getClass().getSimpleName().equals("JComboBox")){
			clickOnCB (e);
			}
	}
	
	
	/**
	 * Manage the actions when we click on the JCombobox.
	 * 
	 * @param e
	 */
	private void clickOnCB(ActionEvent e) {
		JComboBox renderer = (JComboBox) e.getSource();
			String rendu = (String) renderer.getSelectedItem();
			if (canvas != null) {
				canvas.setRenderer(Renderer.getRendererType(rendu));
				setRendererCommand.setCanvas(canvas);
				setRendererCommand.execute();
			}
	}
	
	

	/**
	 * Manage the commands when we click on a button.
	 * 
	 * @param icones
	 */
	private void clickOnMouse(Items icones) {

		switch (icones) {
		case ACCELERATE:
			accelerate.execute();
			break;

		case SLOW:
			slow.execute();
			break;

		case STOP:
			stop.execute();
			break;
		case PLAY:
			playPause.execute();
			break;
		case SAVE_STATS:
			statsCommand.execute();
			break;
		case LOAD:
			JFileChooser choix_fichier = new JFileChooser();
			// choix_fichier.setCurrentDirectory(new java.io.File(
			// "../AntSimulator-Project/resources"));
			choix_fichier.setFileFilter(new PngFileFilter());
			choix_fichier.setFileSelectionMode(JFileChooser.FILES_ONLY);
			int resultat = choix_fichier.showOpenDialog(null);
			if (resultat == JFileChooser.APPROVE_OPTION) {
				LoadImageCommand c = new LoadImageCommand(
						choix_fichier.getSelectedFile(), clock.getSimulator(),
						canvas);
				c.execute();
			}
			break;
		case EXIT:
			exit.execute();
			break;
		case FILE:
			// TODO coming soon.
			break;
		case NEW_NEST:
			canvas.setSelection(Selection.NEST);
			canvas.setSelectedXY(null, null);
			break;
		case OBSTACLE_HERE:
			if (newObstacleCommand != null) {
				newObstacleCommand.execute();
			}
			break;
		case OBSTACLE:
			canvas.setSelection(Selection.OBSTACLE);
			canvas.setSelectedXY(null, null);
			break;
		case SELECTION:
			canvas.setSelection(Selection.SELECTION);
			canvas.setSelectedXY(null, null);
			break;
		case RECENT_MAP:
			// TODO coming soon.
			break;
		case RESOURCE:
			canvas.setSelection(Selection.RESOURCE);
			canvas.setSelectedXY(null, null);
			break;
		case RESOURCE_HERE:
			if (newResourceCommand != null) {
				newResourceCommand.execute();
			}
			break;
		case DELETE:
			if (deleteCommand != null) {
				deleteCommand.setCanvas(frame.getMainPanel().getCanvas());
				deleteCommand.execute();
			}
		default:
			break;
		}
	}

	public void setNewResourceCommand(NewResourceCommand newResourceCommand) {
		this.newResourceCommand = newResourceCommand;
	}

	public void setNewObstacleCommand(NewObstacleCommand newObstacleCommand) {
		this.newObstacleCommand = newObstacleCommand;
	}

	public void setCanvas(Canvas canvas) {
		this.canvas = canvas;
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// do nothing

	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// do nothing

	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// do nothing

	}

	@Override
	public void mouseExited(MouseEvent e) {
		// do nothing
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		if (e.getComponent() instanceof JButton) {
			JButton button = (JButton) e.getComponent();
			if (button.isEnabled()) {
				if (SwingUtilities.isLeftMouseButton(e)) {
					// button.setVisible(false);
					// button.setBounds(new
					// Rectangle(e.getX(),e.getY(),Canvas.NODE_SIZE,
					// Canvas.NODE_SIZE));
					if (button.getTransferHandler() != null) {
						button.getTransferHandler().exportAsDrag(button, e,
								TransferHandler.MOVE);
						if (button.getActionCommand().equals(
								Items.OBSTACLE.getActionCommand())) {
							canvas.setSelection(Selection.OBSTACLE);
						} else if (button.getActionCommand().equals(
								Items.NEW_NEST.getActionCommand())) {
							canvas.setSelection(Selection.NEST);
						} else if (button.getActionCommand().equals(
								Items.RESOURCE.getActionCommand())) {
							canvas.setSelection(Selection.RESOURCE);
						}
					}
				}
			}
		}

	}

	@Override
	public void mouseMoved(MouseEvent e) {
		// do nothing

	}
}
